#include <master.h>
/* sekiOS
 *
 * timer.c - PIT handling
 *
 */

volatile unsigned long long int timer_ticks = 0;	/* system time */

/* changes timer frequency: by default it's 18.2222hz.
 * some engineer at ibm was smoking something funky */
// change timer phase

// PIT Mode 0x34 = Channel 0, Access 3 (Lo/Hi), Mode 2 (Rate Generator)
#define PIT_MODE_C0_LH_M2 ((0 << 6) | (3 << 4) | (2 << 1))

#define PIT_PORT_MODE 0x43
#define PIT_PORT_CHANNEL0 40

void timer_phase(int hz)
{
 // PIT freq 1,193,181.6666r Hz
 int divisor = (3579545 / (3 * hz)); // used to maintain accuracy (NoFrillz)
 outportb(PIT_PORT_MODE, PIT_MODE_C0_LH_M2); // correct mode (Napalm)
 outportb(PIT_PORT_CHANNEL0, divisor & 0xFF);
 outportb(PIT_PORT_CHANNEL0, divisor >> 8);
 dprint("PIT Install @ ~%dHz\n", (1193181 / divisor));
}

/* Handles the timer. In this case, it's very simple: We
*  increment the 'timer_ticks' variable every time the
*  timer fires. By default, the timer is set to fire at
*  18.2222hz, but we set it to 100hz for the sake of simplicity. */
void timer_handler (struct regs *r)
{ 

//  char buf[17];
  /* Increment our tick count */

  timer_ticks++;

  /*
  sprintf(buf, "%16x", timer_ticks);

  printxy((unsigned char *)buf, 80 - 16, 24); 
  */

}

/* Sets up the system clock by installing the timer handler
*  into IRQ0 */
void timer_install ()
{
  /* Installs 'timer_handler' to IRQ0  and sets timer tick to 100hz */
  timer_phase (TIMER_SPEED);
  irq_install_handler (0, timer_handler);
}

/* This will continuously loop until the given time has
*  been reached */
void timer_wait (unsigned long long ticks)
{
  unsigned long long eticks;

  eticks = timer_ticks + ticks;
  while (timer_ticks < eticks);
}
